package cn.fsd.filter;

import cn.fsd.vo.Auth;
import cn.fsd.filter.handler.TokenAuthHandler;
import cn.fsd.filter.handler.UserPassAuthHandler;
import cn.fsd.util.Constants;
import cn.fsd.vo.ResultBean;
import com.alibaba.fastjson.JSON;
import java.io.UnsupportedEncodingException;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class LoginFilter implements GlobalFilter, Ordered {

  @Autowired
  UserPassAuthHandler userPassAuthHandler;
  @Autowired
  TokenAuthHandler tokenAuthHandler;

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    //判断是否为登录
    boolean isLogin = isLoginOut(exchange.getRequest());
    Auth auth;
    if(isLogin){
//      访问登录接口直接放行让用户登录
      return chain.filter(exchange);
    }else{
//      否则对token进行验证
      auth = tokenAuthHandler.authenticate(exchange);
    }
    boolean status = auth.isSuccessful();
    ResultBean data = new ResultBean();

    if(status){
      return chain.filter(exchange);
    }else{
      data.setCode(500);
      data.setMsg(auth.getAuthMsg());
    }
    DataBuffer buffer = null;
    //响应对象
    ServerHttpResponse response = exchange.getResponse();
    try {
      byte[] bytes = JSON.toJSONString(data).getBytes("utf-8");
      buffer = response.bufferFactory().wrap(bytes);

      //设置完成相应，不会继续执行后面的filter
      //response.setComplete();
      response.setStatusCode(HttpStatus.UNAUTHORIZED);
      response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return response.writeWith(Mono.just(buffer));
  }

  public boolean isLoginOut(ServerHttpRequest request){
    String path = request.getPath().toString();
    return Objects.equals(Constants.LOGINPATH,path)||Objects.equals(Constants.LOGOUTPATH,path);
  }

  @Override
  public int getOrder() {
    return Ordered.HIGHEST_PRECEDENCE+1;
  }
}
